package com.code2roc.fastboot.framework.security;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.code2roc.fastboot.framework.util.CommonUtil;
import com.code2roc.fastboot.framework.util.ConvertOp;
import com.code2roc.fastboot.framework.util.ReflectUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Component
public class SQLInjectInterceptor implements HandlerInterceptor {
    @Autowired
    private SecurityConfig securityConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        boolean isvalid = true;
        if(securityConfig.isOpenSQLInject()){
            String contentType = request.getContentType();
            if (StringUtils.isNotBlank(contentType) && contentType.contains("application/json")) {
                //自定义忽略sql注入注解
                HandlerMethod handlerMethod = null;
                if(handler.getClass()==HandlerMethod.class){
                    handlerMethod = (HandlerMethod)handler;
                    if(ReflectUtil.checkClassAnnotationPresent(handlerMethod.getBeanType(), IgnoreSQLInject.class)){
                        return true;
                    }
                    if(ReflectUtil.checkMethodAnnotationPresent(handlerMethod.getMethod(), IgnoreSQLInject.class)){
                        return true;
                    }
                }
                String body = CommonUtil.getBodyString(request);
                try {
                    Object object = JSON.parse(body);
                    if (object instanceof JSONObject) {
                        JSONObject jsonObject = JSONObject.parseObject(body);
                        for (Map.Entry<String, Object> item : jsonObject.entrySet()) {
                            String value = ConvertOp.convert2String(item.getValue());
                            if (SQLInjectUtil.checkSQLInject(value)) {
                                isvalid = false;
                                break;
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (!isvalid) {
                response.sendRedirect(request.getContextPath() + "/frame/error/sqlInjectionError");
            }
        }
        return isvalid;
    }

}
